home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
os2
/
octa209s.zip
/
octave-2.09
/
src
/
utils.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-10
|
11KB
|
551 lines
/*
Copyright (C) 1996 John W. Eaton
This file is part of Octave.
Octave is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
Octave is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Modified by Klaus Gebhardt, 1996 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <climits>
#include <csetjmp>
#include <cstring>
#include <string>
#include <fstream.h>
#include <iostream.h>
#include <strstream.h>
#ifdef HAVE_UNISTD_H
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <unistd.h>
#endif
#if defined (HAVE_TERMIOS_H)
#include <termios.h>
#elif defined (HAVE_TERMIO_H)
#include <termio.h>
#elif defined (HAVE_SGTTY_H)
#include <sgtty.h>
#else
LOSE! LOSE!
#endif
#ifndef HAVE_STRNCASECMP
extern "C" int strncasecmp (const char*, const char*, size_t);
#endif
#include "SLStack.h"
#include "file-ops.h"
#include "oct-cmplx.h"
#include "str-vec.h"
#include <defaults.h>
#include "defun.h"
#include "dir-ops.h"
#include "dirfns.h"
#include "error.h"
#include "gripes.h"
#include "help.h"
#include "input.h"
#include "mappers.h"
#include "oct-hist.h"
#include "oct-obj.h"
#include "pager.h"
#include "pathsearch.h"
#include "sysdep.h"
#include "toplev.h"
#include "unwind-prot.h"
#include "utils.h"
#include "variables.h"
// Top level context (?)
extern jmp_buf toplevel;
// Save a string.
char *
strsave (const char *s)
{
if (! s)
return 0;
int len = strlen (s);
char *tmp = new char [len+1];
tmp = strcpy (tmp, s);
return tmp;
}
// Return to the main command loop in octave.cc.
extern "C" void
jump_to_top_level (void)
{
#if ! defined (__EMX__) || ! defined (OS2)
run_all_unwind_protects ();
#endif
longjmp (toplevel, 1);
}
int
almost_match (const string& std, const string& s, int min_match_len,
int case_sens)
{
int stdlen = std.length ();
int slen = s.length ();
return (slen <= stdlen
&& slen >= min_match_len
&& (case_sens
? (strncmp (std.c_str (), s.c_str (), slen) == 0)
: (strncasecmp (std.c_str (), s.c_str (), slen) == 0)));
}
// Ugh.
int
keyword_almost_match (const char **std, int *min_len, const string& s,
int min_toks_to_match, int max_toks)
{
int status = 0;
int tok_count = 0;
int toks_matched = 0;
if (s.empty () || max_toks < 1)
return status;
char *kw = strsave (s.c_str ());
char *t = kw;
while (*t != '\0')
{
if (*t == '\t')
*t = ' ';
t++;
}
char *beg = kw;
while (*beg == ' ')
beg++;
if (*beg == '\0')
return status;
char **to_match = new char * [max_toks + 1];
const char **s1 = std;
char **s2 = to_match;
if (! s1 || ! s2)
goto done;
s2[tok_count] = beg;
char *end;
while ((end = strchr (beg, ' ')) != 0)
{
*end = '\0';
beg = end + 1;
while (*beg == ' ')
beg++;
if (*beg == '\0')
break;
tok_count++;
if (tok_count >= max_toks)
goto done;
s2[tok_count] = beg;
}
s2[tok_count+1] = 0;
s2 = to_match;
for (;;)
{
if (! almost_match (*s1, *s2, min_len[toks_matched], 0))
goto done;
toks_matched++;
s1++;
s2++;
if (! *s2)
{
status = (toks_matched >= min_toks_to_match);
goto done;
}
if (! *s1)
goto done;
}
done:
delete [] kw;
delete [] to_match;
return status;
}
// Return non-zero if either NR or NC is zero. Return -1 if this
// should be considered fatal; return 1 if this is ok.
int
empty_arg (const char *name, int nr, int nc)
{
int is_empty = 0;
if (nr == 0 || nc == 0)
{
int flag = Vpropagate_empty_matrices;
if (flag < 0)
{
gripe_empty_arg (name, 0);
is_empty = 1;
}
else if (flag == 0)
{
gripe_empty_arg (name, 1);
is_empty = -1;
}
else
is_empty = 1;
}
return is_empty;
}
// See if the given file is in the path.
string
search_path_for_file (const string& path, const string& name)
{
dir_path p (path);
return make_absolute (p.find (name), Vcurrent_directory);
}
DEFUN (file_in_path, args, ,
"file_in_path (PATH, NAME)")
{
octave_value_list retval;
int argc = args.length () + 1;
string_vector argv = args.make_argv ("file_in_path");
if (error_state)
return retval;
if (argc == 3)
{
string path = maybe_add_default_load_path (argv[1]);
string fname = search_path_for_file (path, argv[2]);
if (fname.empty ())
retval = Matrix ();
else
retval = fname;
}
else
print_usage ("file_in_path");
return retval;
}
string
file_in_path (const string& name, const string& suffix)
{
string nm = name;
if (! suffix.empty ())
nm.append (suffix);
if (Vcurrent_directory.empty ())
get_working_directory ("file_in_path");
return search_path_for_file (Vload_path, nm);
}
// See if there is an function file in the path. If so, return the
// full path to the file.
string
fcn_file_in_path (const string& name)
{
string retval;
int len = name.length ();
if (len > 0)
{
if (len > 2 && name [len - 2] == '.' && name [len - 1] == 'm')
retval = file_in_path (name, "");
else
retval = file_in_path (name, ".m");
}
return retval;
}
// See if there is an octave file in the path. If so, return the
// full path to the file.
string
oct_file_in_path (const string& name)
{
string retval;
int len = name.length ();
if (len > 0)
{
if (len > 2 && name [len - 4] == '.' && name [len - 3] == 'o'
&& name [len - 2] == 'c' && name [len - 1] == 't')
retval = file_in_path (name, "");
else
retval = file_in_path (name, ".oct");
}
return retval;
}
const char *
undo_string_escape (char c)
{
if (! c)
return "";
switch (c)
{
case '\a':
return "\\a";
case '\b': // backspace
return "\\b";
case '\f': // formfeed
return "\\f";
case '\n': // newline
return "\\n";
case '\r': // carriage return
return "\\r";
case '\t': // horizontal tab
return "\\t";
case '\v': // vertical tab
return "\\v";
case '\\': // backslash
return "\\\\";
case '"': // double quote
return "\\\"";
default:
{
static char retval[2];
retval[0] = c;
retval[1] = '\0';
return retval;
}
}
}
string
undo_string_escapes (const string& s)
{
string retval;
for (size_t i = 0; i < s.length (); i++)
retval.append (undo_string_escape (s[i]));
return retval;
}
DEFUN (undo_string_escapes, args, ,
"undo_string_escapes (STRING)")
{
octave_value retval;
int nargin = args.length ();
if (nargin == 1 && args(0).is_string ())
retval = undo_string_escapes (args(0).string_value ());
else
print_usage ("undo_string_escapes");
return retval;
}
// This function was adapted from xputenv from Karl Berry's kpathsearch
// library.
void
oct_putenv (const char *var_name, const char *value)
{
static const char **saved_env_items = 0;
static unsigned saved_len;
char *old_item = 0;
int new_len = strlen (var_name) + strlen (value) + 2;
char *new_item = new char [new_len];
sprintf (new_item, "%s=%s", var_name, value);
#ifndef SMART_PUTENV
// Check if we have saved anything yet.
if (! saved_env_items)
{
saved_env_items = new const char * [1];
saved_env_items[0] = var_name;
saved_len = 1;
}
else
{
// Check if we've assigned VAR_NAME before.
unsigned len = strlen (var_name);
for (unsigned i = 0; i < saved_len && ! old_item; i++)
{
if (strcmp (saved_env_items[i], var_name) == 0)
{
old_item = getenv (var_name);
assert (old_item);
// Back up to the `NAME=' in the environment before the
// value that getenv returns.
old_item -= (len + 1);
}
}
if (! old_item)
{
// If we haven't seen VAR_NAME before, save it. Assume it
// is in safe storage.
saved_len++;
const char **tmp = new const char * [saved_len];
for (unsigned i = 0; i < saved_len - 1; i++)
tmp[i] = saved_env_items[i];
tmp[saved_len - 1] = var_name;
delete [] saved_env_items;
saved_env_items = tmp;
}
}
#endif
// As far as I can see there's no way to distinguish between the
// various errors; putenv doesn't have errno values.
if (putenv (new_item) < 0)
error ("putenv (%s) failed", new_item);
#ifndef SMART_PUTENV
// Can't free `new_item' because its contained value is now in
// `environ', but we can free `old_item', since it's been replaced.
delete [] old_item;
#endif
}
static void
warn_old_style_preference (bool val, const string& sval)
{
warning
("preference of \"%s\" is obsolete -- use numeric value of %d instead",
sval.c_str (), (val ? 1 : 0));
}
// Check the value of a string variable to see if it it's ok to do
// something.
//
// return of 1 => always ok.
// return of 0 => never ok.
// return of -1 => ok, but give me warning (default).
int
check_preference (const string& var)
{
int pref = -1;
string val = builtin_string_variable (var);
if (val.empty ())
{
double dval = 0;
if (builtin_real_scalar_variable (var, dval))
pref = NINT (dval);
}
else
{
if (val.compare ("yes", 0, 3) == 0
|| val.compare ("true", 0, 4) == 0)
{
warn_old_style_preference (true, val);
pref = 1;
}
else if (val.compare ("never", 0, 5) == 0
|| val.compare ("no", 0, 2) == 0
|| val.compare ("false", 0, 5) == 0)
{
warn_old_style_preference (false, val);
pref = 0;
}
}
return pref;
}
/*
;;; Local Variables: ***
;;; mode: C++ ***
;;; End: ***
*/